package com.ttl.gatewayservice.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class GateWayGlobalFilter implements GlobalFilter, Ordered {
    @Autowired
    private RedisTemplate redisTemplate;

    public static final String TOKEN_HEADER_KEY = "Access-Token"; // 建议改正拼写
    public static final String USER_ID = "userId";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("============== 网关拦截器启动 ===============");

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String url = request.getURI().getPath();

        // 登录接口直接放行
        if (url.contains("/login")) {
            return chain.filter(exchange);
        }

        String userId = request.getHeaders().getFirst(USER_ID); // 从参数取
        String token = request.getHeaders().getFirst(TOKEN_HEADER_KEY); // 从header取

        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(userId)) {
            log.warn("缺少 userId 或 token 参数");
            return buildErrorResponse(response, "缺少 userId 或 token 参数");
        }

        String redisToken = (String) redisTemplate.opsForValue().get(userId);
        if (redisToken == null || !redisToken.equals(token)) {
            log.warn("Redis token 不存在或不匹配，userId={}, token={}", userId, token);
            return buildErrorResponse(response, "无效的 token，请重新登录");
        }

        log.info("✅ token 校验通过，userId={}，放行请求", userId);
        redisTemplate.opsForValue().set(userId, token, 30, TimeUnit.MINUTES);
        return chain.filter(exchange);
    }

    /**
     * token校验失败，返回错误信息
     * @param response
     * @param message
     * @return
     */
    private Mono<Void> buildErrorResponse(ServerHttpResponse response, String message) {
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        String body = "{\"code\":401,\"msg\":\"" + message + "\"}";
        DataBuffer buffer = response.bufferFactory().wrap(body.getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Mono.just(buffer));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

